package com.tx.schedule.service;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tx.schedule.factory.ScheduleJobFactory;
import com.tx.schedule.model.ScheduleJob;

public class ScheduleService {
	Logger logger = LoggerFactory.getLogger(ScheduleService.class);

	private ScheduleJobServiceInf scheduleJobService;

	private Scheduler scheduler;

	/**
	 * 获取数据库所有任务
	 * 
	 * @return
	 */
	public List<ScheduleJob> getScheduleJobs(int start, int end) {
		return scheduleJobService.getScheduleJobs(start, end);
	};

	/**
	 * 根据jobId获取任务
	 * 
	 * @param jobId
	 *            任务ID
	 * @return
	 */

	public ScheduleJob getScheduleJobById(String jobId) {
		return scheduleJobService.getScheduleJobById(jobId);
	}

	/**
	 * 增加调度任务，同时添加到数据库
	 * 
	 * @param scheduleJob
	 *            调度任务
	 */
	public int addScheduler(ScheduleJob scheduleJob) {

		Scheduler scheduler = getScheduler();
		try {
			ScheduleJobFactory.createSheduler(scheduler, scheduleJob);
			
			if (scheduleJob.isRunOnce()!=null&&scheduleJob.isRunOnce()) {
				ScheduleJobFactory.runOnce(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
			}
		} catch (Exception e) {
			logger.error("恢复任务：[" + scheduleJob.getJobGroup() + "." + scheduleJob.getJobName() + "]失败");
			e.printStackTrace();
			return 0;
		}
		return 1;
	}

	public int insertScheduler(ScheduleJob scheduleJob){
		int effect=scheduleJobService.insert(scheduleJob);
		if (effect>0 && scheduleJob.getJobStatus().equals(ScheduleJob.STATUS_ENABLE)) {
			addScheduler(scheduleJob);
		}
		return effect;
	}
	/**
	 * 更新任务
	 * 
	 * @param scheduleJob
	 *            调度任务
	 */
	public int updateSchedule(ScheduleJob scheduleJob) {
		Scheduler scheduler = getScheduler();
		//如果修改了jobName或groupName,则必须要删除原任务
		ScheduleJob oldJob=scheduleJobService.getScheduleJobById(scheduleJob.getJobId());
		if (!oldJob.getJobGroup().equals(scheduleJob.getJobGroup()) || !oldJob.getJobName().equals(scheduleJob.getJobName())) {
			try {
				ScheduleJobFactory.deleteScheduleJob(scheduler, oldJob);
			} catch (SchedulerException e) {
				e.printStackTrace();
			}
		}
		try {
			ScheduleJobFactory.updateScheduleJob(scheduler, scheduleJob);
			scheduleJobService.updateByPrimaryKey(scheduleJob);
			if (scheduleJob.isRunOnce()!=null && scheduleJob.isRunOnce()) {
				ScheduleJobFactory.runOnce(scheduler, scheduleJob.getJobName(), scheduleJob.getJobGroup());
			}
		} catch (Exception e) {
			logger.error("更新任务：[" + scheduleJob.getJobGroup() + "." + scheduleJob.getJobName() + "]失败");
			e.printStackTrace();
			return 0;
		}
		logger.info("更新任务：[" + scheduleJob.getJobGroup() + "." + scheduleJob.getJobName() + "]成功");
		return 1;
	}

	@PostConstruct
	public void init() {
		logger.info("===============Scheduler job starting init……");
		// 这里获取任务信息数据
		List<ScheduleJob> jobList = scheduleJobService.queryAvailableJobs(0, Integer.MAX_VALUE);
		for (ScheduleJob job : jobList) {
			addScheduler(job);
		}
		logger.info("================Scheduler job init success……");
	}

	/**
	 * 暂停调度器
	 * 
	 * @author 我慧快乐
	 * @param jobId
	 */
	public void pauseSchedule(String jobId) {
		ScheduleJob scheduleJob = scheduleJobService.getScheduleJobById(jobId);
		Scheduler scheduler = getScheduler();
		try {
			ScheduleJobFactory.pauseJob(scheduler, scheduleJob);
		} catch (SchedulerException e) {
			logger.error("暂停任务：[" + scheduleJob.getJobGroup() + "." + scheduleJob.getJobName() + "]失败");
			e.printStackTrace();
			return;
		}
		scheduleJob.setJobStatus("0");
		scheduleJobService.updateByPrimaryKey(scheduleJob);
	}

	/**
	 * 删除调度器
	 * 
	 * @author 我慧快乐
	 * @param jobId
	 */
	public int deleteSchedule(String jobId) {
		ScheduleJob scheduleJob = scheduleJobService.getScheduleJobById(jobId);
		if (scheduleJob.getJobStatus() != null && scheduleJob.getJobStatus().equals(ScheduleJob.STATUS_ENABLE)) {
			Scheduler scheduler = getScheduler();
			try {
				ScheduleJobFactory.deleteScheduleJob(scheduler, scheduleJob);
			} catch (SchedulerException e) {
				logger.error("删除任务：[" + scheduleJob.getJobGroup() + "." + scheduleJob.getJobName() + "]失败");
				e.printStackTrace();
				return 0; // 失败不做物理删除
			}
		}
		return scheduleJobService.deleteByPrimaryKey(scheduleJob);
	}

	/**
	 * 恢复调度器
	 * 
	 * @author 我慧快乐
	 * @param jobId
	 */
	public void resumeSchedule(String jobId) {
		ScheduleJob scheduleJob = scheduleJobService.getScheduleJobById(jobId);
		Scheduler scheduler = getScheduler();
		addScheduler(scheduleJob);
		try {
			ScheduleJobFactory.resumeJob(scheduler, scheduleJob);
			scheduleJob.setJobStatus("1");
			scheduleJobService.updateByPrimaryKey(scheduleJob);
		} catch (SchedulerException e) {
			logger.error("恢复任务：[" + scheduleJob.getJobGroup() + "." + scheduleJob.getJobName() + "]失败");
			e.printStackTrace();
		}
	}

	/**
	 * 执行一次任务
	 * 
	 * @author 我慧快乐
	 * @param job
	 */
	public void runOnce(ScheduleJob job) {
		Scheduler scheduler = getScheduler();
		try {
			ScheduleJobFactory.runOnce(scheduler, job);
		} catch (SchedulerException e) {
			logger.error("执行一次任务：[" + job.getJobGroup() + "." + job.getJobName() + "]失败");
			e.printStackTrace();
		}

	}

	/**
	 * 通过job的主键ID调用执行一次任务
	 * 
	 * @author 我慧快乐
	 * @date 2017年1月3日上午11:18:58
	 * @Title: runOnce
	 * @param jobId
	 *            任务ID
	 * @throws SchedulerException
	 */
	public void runOnce(String jobId) {
		ScheduleJob scheduleJob = scheduleJobService.getScheduleJobById(jobId);
		this.runOnce(scheduleJob);
	}

	/**
	 * 根据主任务编号获取子任务
	 * 
	 * @param childJobIds
	 *            子任务编号，逗号分隔
	 * @return
	 */
	public List<ScheduleJob> getChildSchedule(String childJobIds) {
		List<ScheduleJob> childSchedules = null;
		if (childJobIds != null && !"".equals(childJobIds)) {
			childSchedules = new ArrayList<>();
			String[] childIds = childJobIds.split(",");
			for (String jobId : childIds) {
				ScheduleJob scheduleJob = scheduleJobService.getScheduleJobById(jobId);
				if (scheduleJob != null) {
					childSchedules.add(scheduleJob);
				}
			}
		}

		return childSchedules;
	}

	public Scheduler getScheduler() {
		return scheduler;
	}

	public ScheduleJobServiceInf getScheduleJobService() {
		return scheduleJobService;
	}

	public void setScheduleJobService(ScheduleJobServiceInf scheduleJobService) {
		this.scheduleJobService = scheduleJobService;
	}

	public void setScheduler(Scheduler scheduler) {
		this.scheduler = scheduler;
	}

}
